﻿using System.Collections.Generic;
using System.IO;
using NPOI.HSSF.UserModel;
using NPOI.POIFS.FileSystem;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Ornament.ImportHelper;

namespace Fee.IO.Importers
{
    public abstract class BaseImporter<T> : IImportor where T : FeeDbContext
    {
        private readonly RowToObject _convertTo;
        private readonly bool _saveInDb;

        protected BaseImporter(T context, bool saveInDb)
        {
            Context = context;
            _saveInDb = saveInDb;
            _convertTo = ConverTo;
        }

        public T Context { get; }

        /// <summary>
        ///     校检文件标题
        /// </summary>
        public bool Import(string file, out IList<ImportResultItem> importResult, out string resultFilePath)
        {
            resultFilePath = null;
            var isExcel2004 = file.EndsWith(".xls");
            var excelManager = new ExcelImportManager<T>(_convertTo, isExcel2004);

            var isValidate = excelManager.Read(file, out importResult);

            if (isValidate && _saveInDb)
            {
                SaveToDb(importResult, Context);
                Context.SaveChanges();
            }


            OnCompleteReadFile(importResult);
            resultFilePath = WriteImportResult(importResult, file);

            return isValidate;
        }

        public virtual void SaveToDb(IList<ImportResultItem> importResult, T t)
        {
            var i = 0;
            foreach (var data in importResult)
                foreach (var obj in data.Data)
                {

                    Context.Update(obj);
                    if (i > 200)
                        Context.SaveChanges();

                    i++;
                }

            Context.SaveChanges();
        }

        protected virtual void OnCompleteReadFile(IList<ImportResultItem> items)
        {
        }

        protected abstract bool ConverTo(IList<string> rowStringInfo, out ImportResultItem item);

        private string WriteImportResult(IList<ImportResultItem> importResults, string file)
        {
            var excelPath = new FileInfo(file);
            var fileStream = excelPath.Open(FileMode.Open, FileAccess.Read);
            var isExcel2003 = file.EndsWith(".xls");
            var workbook =
                isExcel2003
                    ? new HSSFWorkbook(new POIFSFileSystem(fileStream))
                    : (IWorkbook)new XSSFWorkbook(fileStream);

            var sheet = workbook.GetSheetAt(0);

            var excelRow = sheet.GetRow(0);
            var lastCellNumber = excelRow.LastCellNum;


            foreach (var importResult in importResults)
            {
                excelRow = sheet.GetRow(importResult.Row);
                var lastCell = excelRow.GetCell(lastCellNumber + 1, MissingCellPolicy.CREATE_NULL_AS_BLANK);
                if (importResult.HasError)
                {
                    var sb = importResult.GetErrors();
                    lastCell.SetCellValue(sb);
                }
                else
                {
                    lastCell.SetCellValue("数据正确");
                }
            }

            //Write to result file 
            var path = Path.Combine(excelPath.Directory.FullName, excelPath.Name + "-结果" + excelPath.Extension);
            var index = 1;
            while (File.Exists(path))
            {
                path = Path.Combine(excelPath.Directory.FullName,
                    excelPath.Name + "-结果" + index + excelPath.Extension);
                index++;
            }

            var resultFilePath = new FileInfo(path);
            using (var stream = resultFilePath.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                workbook.Write(stream);
            }

            return resultFilePath.Name;
        }
    }
}